async/await 您所在的位置:网站首页 node 同步执行 async/await

async/await

2024-07-18 08:29| 来源: 网络整理| 查看: 265

首先,要明白异步跟同步,参考下方博客的案例介绍:async/await让异步操作同步执行的方法详解 - dreamw - 博客园 (cnblogs.com)icon-default.png?t=N7T8https://www.cnblogs.com/wl-blog/p/15136449.html

function fn1(){ console.log(111) setTimeout(function(){ console.log('wait me 3000') },3000) } function fn2(){ console.log(222) } fn1(); fn2(); //输出结果: //111 //222 //wait me 3000

这里的setTimeout方法就是异步操作,它会在同步操作之后才执行,所以在执行了fn1后,同步执行了fn2,最后才执行setTimeout方法

 你可能会想,这个setTimeout延时了3秒才执行,肯定比fn2慢,那下面把延时时间设为0看一下

function fn1(){ console.log(111) setTimeout(function(){ console.log('wait me 0') },0) } function fn2(){ console.log(222) } fn1(); fn2(); //运行结果: //111 //222 //wait me 0

即使设置的等待时间是0,仍然会被当作异步方法,要等到同步方法执行完才会执行它 

注意:利用setTimeout=>0这个异步特性,可以修改方法中的方法的执行顺序 function fn1(){ console.log(111) //通过设置setTimeout=>0,不延时执行方法,但是能将fn2放到同步方法执行完之后再执行 //也就是等到fn1,fn3执行完,再执行fn2,即使fn2再fn1中 setTimeout(fn2,0) } function fn2(){ console.log(222) } function fn3(){ console.log(333) } fn1(); fn3(); //输出结果: //111 //333 //222

这样,既可以不延时调用fn2方法,又可以修改fn2方法的调用顺序,在fn1方法和fn3方法执行完后再调用fn2方法。

 以上就是对异步、同步的简单举例,接下来重点说明一下如何通过async、await 或者promise.then()来讲异步操作同步化

async和await

async:它修饰的方法,返回的数据就会是个promise对象(可单独使用)

await:意思是等待执行完它修饰的方法,再往下执行,它会阻塞后面的代码,也就是同步

await 如果得到的是 Promise 对象,则得到其 resolve值需要配合async使用 例子1: async function fn(){ return '111' } console.log(fn()); //Promise { '111' } 或者: fn().then(data=>{ console.log(data) //111 }

使用async修饰的方法就会返回promise对象,

        如果一个函数加了async关键词,这个函数又有返回值,在调用这个函数时,如果函数执行成功,内部会调用Promise.resolve()方法返回一个Promise对象,如果函数执行出现异常,就会调用Promise.reject()方法返回一个promise 对象

要想获取到async函数的执行结果,就要调用Promise.then()   例子2: function f() { //最好是将方法返回成promise对象,用resolve,不然些复杂的函数,会导致await没效果 return new Promise(resolve =>{ resolve('hhh') }) } async function doSomething1(){ let x = await f(); return x } doSomething1().then(res=>{ console.log(res) }) 打印结果: hhh

1、函数前面会加一个async修饰符,就会证明这个函数是一个异步函数;(也就是说这里的doSomething1函数是个异步函数)

2、await 是个运算符,用于组成表达式,它会阻塞后面的代码(也就是说这里的f()函数被转换成了同步函数,即使里面有异步方法,也会执行完再往下执行)

3、await 如果得到的是 Promise 对象,则得到其 resolve值

例子3: async function doSomething1(){ //最好是将方法返回成promise对象,用resolve,不然些复杂的函数,会导致await没效果 let x = await 'hhh' //这里await修饰的不是一个方法,也不是一个promise对象 return x } console.log(doSomething1()) //Promise {} ==> async修饰的函数,就会返回promise对象 doSomething1().then(res => { console.log(res) //hhh ==> 通过.then获取到promise对象的resolve出来的值 }) 另一种情况: async function doSomething1(){ let x = await fn2() //即使fn2返回的不是promise,也可以用await修饰 return x } function fn2(){ return '123456' } doSomething1().then(res => { console.log(res) //123456 ==>因为是用async修饰的函数,所以可以用.then获取到返回的数据 })

 1、async修饰的方法返回的是一个promise对象,其 return 返回的值,会成为 .then() 方法回调函数的参数;

2、await修饰的方法如果得到的不是promise对象,也是可以的,得到的是啥就是啥,仍然会有await的阻塞效果(同步)。

例子4: function fn1(){ //最好是将方法返回成promise对象,用resolve,不然些复杂的函数,会导致await没效果 return new Promise(resolve=>{ setTimeout(function(){ msg='wait me 3000'; resolve(msg) },3000); }); } async function asyncCall(){ var result=await fn1(); console.log(result); } asyncCall(); 运行结果: 三秒后,会输出: wait me 3000

        这是因为有await将fn1方法改成了同步方法,阻塞了后面的console.log(result),等到执行完fn1中的异步方法后,拿到了resolve的返回值,才去执行下一步。

        如上图所示,如果不适用async await将fn1方法转成同步方法,那么因为fn1中的异步操作会在console.log(result)这个同步方法执行完后才执行,也就没有拿到resolve的返回值,自然就会输出undefined

  注意:try catch只能用来捕获【同步函数】,不能用来捕获【异步函数】 try{ fn() } catch(error){ console.error(error); }

try catch只能捕获【同步方法】的错误,如果fn是个异步方法,就会报错,捕获不到,所以,一般都是对 async await修饰的方法用try catch,因为async await修饰的方法就会变成【同步方法】

看完上面的例子,你现在应该知道,如何把函数转成同步来执行了,接下来用一个例子来说明一下:

async function a () { return new Promise((resolve, reject) => { resolve('123456') }) } //通过async修饰后的方法,可以用.then来获取返回值 a().then(res => { console.log(res) // 123456 }) 或者: async function a () { return '123456' } a().then(res => { console.log(res) //123456 })

 通过async修饰后的方法,可以用.then来获取返回值,然后我们就可以在.then中进行下一个方法的调用了,这样既能规定好哪一个方法先执行,哪一个后执行

当然,你也可以用 await,直接把想要的方法转换成同步方法

async a () { //最好是将方法返回成promise对象,用resolve,不然些复杂的函数,会导致await没效果 return new Promise((resolve, reject) => { resolve('123456') }) } //通过await将方法a()转成同步的,执行完a方法之后,才会往下执行 var result=await a(); console.log(result); b() c() .....

有时候,你设置了一个async方法,然后里面return一个promise对象,然后这个对象里面还要调用一个await方法,那么【eslint规范】会报错提示:promise中不建议使用await,你可以直接利用vscode的错误修复功能,alt+.  在报错行添加一行注释,取消eslint的报错,这样就能正常运行了。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

      专题文章
        CopyRight 2018-2019 实验室设备网 版权所有